local login = require "loginserver"
local crypt = require "skynet.crypt"
local skynet = require "skynet"
local runconfig = require "runconfig"

local loginserver_host = skynet.getenv("loginserver_host") or "0.0.0.0"
local loginserver_port = tonumber(skynet.getenv("loginserver_port")) or 8080
local loginserver_slave_instance = tonumber(skynet.getenv("loginserver_slave_instance")) or 2

local server = {
	host = loginserver_host,
	port = loginserver_port,
	multilogin = false,	-- disallow multilogin
	name = runconfig[skynet.getenv("node")].login.servername,
	instance = loginserver_slave_instance,
}

local server_list = {} -- { gate_servername : gated }
local user_online = {}
local user_login = {}

local online_counts = 0	-- 在线人数

function server.auth_handler(token)
	-- the token is base64(user\tpassword)@base64(server)
	local user_pass, server = token:match("([^@]+)@(.+)")

	user_pass = crypt.base64decode(user_pass)
	server = crypt.base64decode(server)

	-- auth: return uid
	assert(user_pass == "cauchy\t123", "Invalid password")
	local uid = 1 -- assume uid = 1

	return server, uid
end

function server.login_handler(server, uid, secret)
	-- print(string.format("%s@%s is login, secret is %s", uid, server, crypt.hexencode(secret)))
	local gameserver = assert(server_list[server], "Unknown server")
	-- only one can login, because disallow multilogin

	local last = user_online[uid]
	if last then
		skynet.call(last.gated, "lua", "kick", uid, last.subid)
	end
	if user_online[uid] then
		error(string.format("user %s is already online", uid))
	end

	local subid = tostring(skynet.call(gameserver, "lua", "login", uid, secret))
	
	user_online[uid] = { 
		uid = tostring(uid),
		subid = subid , 
		gated = gameserver,  -- 网关服务地址
		servername = server, -- 网关服务名
		secret = secret,
	}

	online_counts = online_counts + 1

	return cjson.encode(user_online[uid])
end

local CMD = {}

function CMD.register_gate(server, address)
	server_list[server] = address
end

function CMD.logout(uid, subid)
	local u = user_online[uid]
	if u then
		print(string.format("%s@%s is logout", uid, u.server))
		user_online[uid] = nil

		online_counts = online_counts - 1
	end
end

function server.command_handler(command, ...)
	local f = assert(CMD[command])
	return f(...)
end

login(server)
